package Compation;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 *
 */
public class hasValidPath {
    private int[][] grid;

    private int m, n;

    // 定义入口,入口和出口是相对的，若出口变为入口，则入口变为出口
    private Map<Integer, int[]> path1 = new HashMap<>();

    // 定义出口
    private Map<Integer, int[]> path2 = new HashMap<>();

    public boolean hasValidPath(int[][] grid) {
        this.grid = grid;
        if (grid == null || grid[0].length == 0) {
            return false;
        }
        this.m = m;
        this.n = n;
        initPath1();
        initPath2();
        boolean res = dfs(0, 0);
        return res;
    }

    private boolean dfs(int r, int c) {
        if (r == m - 1 && c == n - 1) {
            return true;
        }
        int[] direction1 = path1.get(grid[r][c]);
        int[] direction2 = path2.get(grid[r][c]);
        int[] nextPos1 = {r + direction1[0], c + direction1[1]};
        int[] nextPos2 = {r + direction2[0], c + direction2[1]};
        if (isValid(nextPos1, r, c)) {
            return dfs(nextPos1[0], nextPos1[1]);
        }
        if (isValid(nextPos2, r, c)) {
            return dfs(nextPos2[0], nextPos2[1]);
        }
        return false;
    }

    private boolean isValid(int[] nextPos, int r, int c) {
        if (nextPos[0] < 0 || nextPos[0] >= m || nextPos[1] < 0 || nextPos[1] >= n) {
            return false;
        }
        int[] direction1 = path1.get(grid[nextPos[0]][nextPos[1]]);
        int[] direction2 = path2.get(grid[nextPos[0]][nextPos[1]]);
        int[] startPos1 = {nextPos[0] + direction1[0], nextPos[1] + direction1[1]};
        int[] startPos2 = {nextPos[0] + direction2[0], nextPos[1] + direction2[1]};
        int[] curPos = {r, c};
        if (Arrays.equals(curPos, startPos1) || Arrays.equals(curPos, startPos2)) {
            return true;
        }
        return false;
    }

    private void initPath1() {
        path1.put(1, new int[]{0, -1});
        path1.put(2, new int[]{-1, 0});
        path1.put(3, new int[]{0, -1});
        path1.put(4, new int[]{0, 1});
        path1.put(5, new int[]{0, -1});
        path1.put(6, new int[]{-1, 0});
    }

    private void initPath2() {
        path1.put(1, new int[]{0, 1});
        path2.put(2, new int[]{1, 0});
        path2.put(3, new int[]{1, 0});
        path2.put(4, new int[]{0, 1});
        path2.put(5, new int[]{-1, 0});
        path2.put(6, new int[]{0, 1});
    }
}
